package com.piece.core.framework.util.net;

import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.framework.util.string.StringUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.jar.JarFile;

public class URLUtil {

    public static String build(String url, Map<String, String> params) {
        if (null == params || params.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder(url);
        if (url.indexOf("?") == -1) {
            sb.append("?");
        }
        sb.append(appendQuery(params));
        return sb.toString();
    }

    public static String appendQuery(Map<String, String> paramToMap) {
        if (null == paramToMap || paramToMap.isEmpty()) {
            return null;
        }
        StringBuffer url = new StringBuffer();
        boolean isFirst = true;
        for (Map.Entry entry : paramToMap.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                url.append("&");
            }
            url.append((String) entry.getKey()).append("=");
            String value = (String) entry.getValue();
            if (StringUtil.isNotEmpty(value)) {
                url.append(URLEncoder.PATH_SEGMENT.encode(value, StandardCharsets.UTF_8));
            }
        }
        return url.toString();
    }

    public static String appendQueryFromRequest(Map<String, String[]> paramToMap) {
        if (null == paramToMap || paramToMap.isEmpty()) {
            return null;
        }
        StringBuffer url = new StringBuffer();
        boolean isFirst = true;
        for (Map.Entry entry : paramToMap.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                url.append("&");
            }
            url.append((String) entry.getKey()).append("=");
            String[] value = (String[]) entry.getValue();
            if (null != value) {
                url.append(StringUtil.join(value));
                //url.append(URLEncoder.PATH_SEGMENT.encode(StringUtil.join(value), StandardCharsets.UTF_8));
            }
        }
        return url.toString();
    }

    public static String buildQuery(String url, String key, String value) {
        URLBuilder builder = URLBuilder.of(url, Charset.defaultCharset());
        // 先移除
        Map<CharSequence, CharSequence> query = (Map<CharSequence, CharSequence>) BeanUtil.getFieldValue(builder.getQuery(), "query");
        query.remove(key);
        // 后添加
        builder.addQuery(key, value);
        return builder.build();
    }

    public static URL url(String url) {
        return url(url, null);
    }

    public static URL url(String url, URLStreamHandler handler) {
        if (url.startsWith("classpath:")) {
            url = url.substring("classpath:".length());
            return URLUtil.class.getClassLoader().getResource(url);
        } else {
            try {
                return new URL(null, url, handler);
            } catch (MalformedURLException var5) {
                try {
                    return (new File(url)).toURI().toURL();
                } catch (MalformedURLException var4) {
                    throw new RuntimeException(var5);
                }
            }
        }
    }

    public static URI getStringURI(CharSequence content) {
        String contentStr = StringUtil.addPrefixIfNot(content, "string:///");
        return URI.create(contentStr);
    }

    public static URL toUrlForHttp(String urlStr) {
        return toUrlForHttp(urlStr, null);
    }

    public static URL toUrlForHttp(String urlStr, URLStreamHandler handler) {
        urlStr = encodeBlank(urlStr);

        try {
            return new URL(null, urlStr, handler);
        } catch (MalformedURLException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static String encodeBlank(CharSequence urlStr) {
        if (null == urlStr) {
            return null;
        } else {
            int len = urlStr.length();
            StringBuilder sb = new StringBuilder(len);

            for(int i = 0; i < len; ++i) {
                char c = urlStr.charAt(i);
                if (StringUtil.isBlankChar(c)) {
                    sb.append("%20");
                } else {
                    sb.append(c);
                }
            }

            return sb.toString();
        }
    }

    public static String encodeAll(String url) {
        return encodeAll(url, StandardCharsets.UTF_8);
    }

    public static String encodeAll(String url, Charset charset) {
        return null != charset && !StringUtil.isEmpty(url) ? URLEncoder.ALL.encode(url, charset) : url;
    }

    public static String encode(String url) {
        return encode(url, StandardCharsets.UTF_8);
    }

    public static String encode(String url, Charset charset) {
        if (StringUtil.isEmpty(url)) {
            return url;
        } else {
            if (null == charset) {
                charset = Charset.defaultCharset();
            }

            return URLEncoder.DEFAULT.encode(url, charset);
        }
    }

    public static String encodeQuery(String url) {
        return encodeQuery(url, StandardCharsets.UTF_8);
    }

    public static String encodeQuery(String url, Charset charset) {
        if (StringUtil.isEmpty(url)) {
            return url;
        } else {
            if (null == charset) {
                charset = Charset.defaultCharset();
            }

            return URLEncoder.QUERY.encode(url, charset);
        }
    }

    public static String encodePathSegment(String url) {
        return encodePathSegment(url, StandardCharsets.UTF_8);
    }

    public static String encodePathSegment(String url, Charset charset) {
        if (StringUtil.isEmpty(url)) {
            return url;
        } else {
            if (null == charset) {
                charset = Charset.defaultCharset();
            }

            return URLEncoder.PATH_SEGMENT.encode(url, charset);
        }
    }

    public static String decode(String url) {
        return decode(url, "UTF-8");
    }

    public static String decode(String content, Charset charset) {
        return null == charset ? content : URLDecoder.decode(content, charset);
    }

    public static String decode(String content, Charset charset, boolean isPlusToSpace) {
        return null == charset ? content : URLDecoder.decode(content, charset, isPlusToSpace);
    }

    public static String decode(String content, String charset) {
        return decode(content, Charset.forName(charset));
    }

    public static String getPath(String uriStr) {
        return toURI(uriStr).getPath();
    }

    public static String getDecodedPath(URL url) {
        if (null == url) {
            return null;
        } else {
            String path = toURI(url).getPath();
            return null != path ? path : url.getPath();
        }
    }

    public static URI toURI(URL url) {
        return toURI(url, false);
    }

    public static URI toURI(URL url, boolean isEncode) {
        return null == url ? null : toURI(url.toString(), isEncode);
    }

    public static URI toURI(String location) {
        return toURI(location, false);
    }

    public static URI toURI(String location, boolean isEncode) {
        if (isEncode) {
            location = encode(location);
        }

        try {
            return new URI(StringUtil.trim(location));
        } catch (URISyntaxException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static boolean isFileURL(URL url) {
        String protocol = url.getProtocol();
        return "file".equals(protocol) || "vfsfile".equals(protocol) || "vfs".equals(protocol);
    }

    public static boolean isJarURL(URL url) {
        String protocol = url.getProtocol();
        return "jar".equals(protocol) || "zip".equals(protocol) || "vfszip".equals(protocol) || "wsjar".equals(protocol);
    }

    public static boolean isJarFileURL(URL url) {
        return "file".equals(url.getProtocol()) && url.getPath().toLowerCase().endsWith(".jar");
    }

    public static InputStream getStream(URL url) {
        try {
            return url.openStream();
        } catch (IOException var2) {
            throw new RuntimeException(var2);
        }
    }

    public static JarFile getJarFile(URL url) {
        try {
            JarURLConnection urlConnection = (JarURLConnection)url.openConnection();
            return urlConnection.getJarFile();
        } catch (IOException var2) {
            throw new RuntimeException(var2);
        }
    }
}
